package jmvm.schemes;


import java.awt.Point;
import java.util.ArrayList;

import jmvm.components.*;
import jmvm.gui.GuiLabel;
import jmvm.gui.GuiLine;
import jmvm.gui.GuiScheme;



public class MemOper {

	public static IntToBools ABUSBits;
	
	public static NOT not_NotRDBUS, not_select, not_NotWRBUS;
	public static AND rdMEM, select, wrMEM;
	public static MEM RAM;

	public static TSB MEMout, fcMEM;

	////////////
	//////////// Grafika
	////////////
	
	public static GuiScheme gui;

	public static GuiScheme getGui() {
		return gui;
	}
	
	public static void gui() {

		GuiLine line; // Pomocna promenljiva
		gui = new GuiScheme("jmvm/jmvm/images/MemOper.png");
		
		ArrayList<ArrayList<Point>> sections;
		ArrayList<Point> points;

		
		// 
		// 
		sections=new ArrayList<ArrayList<Point>>();
		points=new ArrayList<Point>();
		points.add(new Point(102,49));
		points.add(new Point(125,49));
		sections.add(points);
		line=new GuiLine(sections,Bus.NotRDBUS());
		gui.addLine(line);

		//
		//
		sections=new ArrayList<ArrayList<Point>>();
		points=new ArrayList<Point>();
		points.add(new Point(125,188));
		points.add(new Point(103,188));
		sections.add(points);
		line=new GuiLine(sections,Bus.NotWRBUS());
		gui.addLine(line);

		//
		//
		sections=new ArrayList<ArrayList<Point>>();
		points=new ArrayList<Point>();
		points.add(new Point(102,261));
		points.add(new Point(122,261));
		sections.add(points);
		line=new GuiLine(sections,Bus.NotFCBUS());
		gui.addLine(line);

		//
		//
		sections=new ArrayList<ArrayList<Point>>();
		points=new ArrayList<Point>();
		points.add(new Point(103,93));
		points.add(new Point(118,93));
		points.add(new Point(118,105));
		points.add(new Point(126,105));
		sections.add(points);
		line=new GuiLine(sections,ABUSBits.getOut(15));
		gui.addLine(line);

		//
		//
		sections=new ArrayList<ArrayList<Point>>();
		points=new ArrayList<Point>();
		points.add(new Point(102,110));
		points.add(new Point(110,110));
		points.add(new Point(110,114));
		points.add(new Point(125,114));
		sections.add(points);
		line=new GuiLine(sections,ABUSBits.getOut(14));
		gui.addLine(line);

		//
		//
		sections=new ArrayList<ArrayList<Point>>();
		points=new ArrayList<Point>();
		points.add(new Point(103,127));
		points.add(new Point(110,127));
		points.add(new Point(110,122));
		points.add(new Point(125,122));
		sections.add(points);
		line=new GuiLine(sections,ABUSBits.getOut(13));
		gui.addLine(line);

		//
		//
		sections=new ArrayList<ArrayList<Point>>();
		points=new ArrayList<Point>();
		points.add(new Point(103,143));
		points.add(new Point(118,143));
		points.add(new Point(118,131));
		points.add(new Point(125,131));
		sections.add(points);
		line=new GuiLine(sections,ABUSBits.getOut(12));
		gui.addLine(line);

		//
		//
		sections=new ArrayList<ArrayList<Point>>();
		points=new ArrayList<Point>();
		points.add(new Point(156,118));
		points.add(new Point(176,118));
		points.add(new Point(176,60));
		points.add(new Point(183,60));
		sections.add(points);
		line=new GuiLine(sections,not_select.getOut(0));
		gui.addLine(line);

		//
		//
		sections=new ArrayList<ArrayList<Point>>();
		points=new ArrayList<Point>();
		points.add(new Point(176,119));
		points.add(new Point(176,175));
		points.add(new Point(183,175));
		sections.add(points);
		line=new GuiLine(sections,not_select.getOut(0));
		gui.addLine(line);

		//
		//
		sections=new ArrayList<ArrayList<Point>>();
		points=new ArrayList<Point>();
		points.add(new Point(156,49));
		points.add(new Point(183,49));
		sections.add(points);
		line=new GuiLine(sections,not_NotRDBUS.getOut(0));
		gui.addLine(line);

		//
		//
		sections=new ArrayList<ArrayList<Point>>();
		points=new ArrayList<Point>();
		points.add(new Point(156,188));
		points.add(new Point(183,188));
		sections.add(points);
		line=new GuiLine(sections,not_NotWRBUS.getOut(0));
		gui.addLine(line);

		//
		//
		sections=new ArrayList<ArrayList<Point>>();
		points=new ArrayList<Point>();
		points.add(new Point(208,55));
		points.add(new Point(275,55));
		points.add(new Point(275,97));
		points.add(new Point(295,97));
		sections.add(points);
		line=new GuiLine(sections,rdMEM.getOut(0));
		gui.addLine(line);

		//
		//
		sections=new ArrayList<ArrayList<Point>>();
		points=new ArrayList<Point>();
		points.add(new Point(208,181));
		points.add(new Point(275,181));
		points.add(new Point(275,139));
		points.add(new Point(294,139));
		sections.add(points);
		line=new GuiLine(sections,wrMEM.getOut(0));
		gui.addLine(line);

		//
		//
		sections=new ArrayList<ArrayList<Point>>();
		points=new ArrayList<Point>();
		points.add(new Point(165,261));
		points.add(new Point(151,261));
		sections.add(points);
		line=new GuiLine(sections,new Pin(true));
		gui.addLine(line);

		//
		//
		sections=new ArrayList<ArrayList<Point>>();
		points=new ArrayList<Point>();
		points.add(new Point(138,280));
		points.add(new Point(138,267));
		sections.add(points);
		line=new GuiLine(sections,MemUprav.fcMEM());
		gui.addLine(line);

		//
		//
		sections=new ArrayList<ArrayList<Point>>();
		points=new ArrayList<Point>();
		points.add(new Point(354,172));
		points.add(new Point(354,255));
		points.add(new Point(440,255));
		sections.add(points);
		line=new GuiLine(sections,RAM.getOut(0));
		gui.addLine(line);

		//
		//
		sections=new ArrayList<ArrayList<Point>>();
		points=new ArrayList<Point>();
		points.add(new Point(465,255));
		points.add(new Point(522,255));
		sections.add(points);
		line=new GuiLine(sections,MEMout.getOut(0));
		gui.addLine(line);

		//
		//
		sections=new ArrayList<ArrayList<Point>>();
		points=new ArrayList<Point>();
		points.add(new Point(453,271));
		points.add(new Point(453,261));
		sections.add(points);
		line=new GuiLine(sections,MemUprav.MEMout.getOut(0));
		gui.addLine(line);

		//
		//
		sections=new ArrayList<ArrayList<Point>>();
		points=new ArrayList<Point>();
		points.add(new Point(433,172));
		points.add(new Point(433,213));
		points.add(new Point(521,213));
		sections.add(points);
		line=new GuiLine(sections,Bus.DBUS());
		gui.addLine(line);

		//
		//
		sections=new ArrayList<ArrayList<Point>>();
		points=new ArrayList<Point>();
		points.add(new Point(521,171));
		points.add(new Point(521,297));
		points.add(new Point(523,297));
		points.add(new Point(523,171));
		sections.add(points);
		line=new GuiLine(sections,Bus.DBUS());
		gui.addLine(line);

		//
		//
		sections=new ArrayList<ArrayList<Point>>();
		points=new ArrayList<Point>();
		points.add(new Point(494,119));
		points.add(new Point(521,119));
		points.add(new Point(521,117));
		points.add(new Point(494,117));
		sections.add(points);
		line=new GuiLine(sections,Bus.ABUS());
		gui.addLine(line);

		//
		//
		
		gui.addLabel(new GuiLabel(534, 243, Bus.DBUS()));
		gui.addLabel(new GuiLabel(502, 134, Bus.ABUS()));

	}
	/////////////
	/////////////
	/////////////
	
	public static void init() {
		
		////
		ABUSBits = new IntToBools(16, 16);
		////
		
		not_NotRDBUS = new NOT();
		not_select = new NOT();
		not_NotWRBUS = new NOT();
		
		rdMEM = new AND();
		wrMEM = new AND();
		select = new AND(4);
		
		RAM = new MEM(64 * 1024); // 64 Kb
		RAM.getOut(0).setIsInt();
		RAM.getOut(0).setNumOfLines(8);
		//RAM.setClock(3);
		
		MEMout = new TSB();
		MEMout.getOut(0).setNumOfLines(8);
		fcMEM = new TSB();
		fcMEM.getOut(0).setIsBool();
	
	}
	
	public static void connect() {
		
		////
		ABUSBits.setInputPin(0, Bus.ABUS());
		////
		
		not_NotRDBUS.setInputPin(0, Bus.NotRDBUS());
		not_select.setInputPin(0, select.getOut(0));
		not_NotWRBUS.setInputPin(0, Bus.NotWRBUS());
		
		rdMEM.setInputPin(0, not_NotRDBUS.getOut(0));
		rdMEM.setInputPin(1, not_select.getOut(0));
		
		wrMEM.setInputPin(0, not_NotWRBUS.getOut(0));
		wrMEM.setInputPin(1, not_select.getOut(0));
		
		select.setInputPin(0, ABUSBits.getOut(15));
		select.setInputPin(1, ABUSBits.getOut(14));
		select.setInputPin(2, ABUSBits.getOut(13));
		select.setInputPin(3, ABUSBits.getOut(12));
		
		RAM.setRead(rdMEM.getOut(0));
		RAM.setWrite(wrMEM.getOut(0));
		RAM.setInputPin(0, Bus.ABUS());
		RAM.setInputPin(1, Bus.DBUS());

		MEMout.setCtrl(MemUprav.MEMout());
		MEMout.setInputPin(0, RAM.getOut(0));
		Bus.addOnDBUS(MEMout.getOut(0));
		
		fcMEM.setCtrl(MemUprav.fcMEM());
		fcMEM.setInputPin(0, new Pin(false));;
		Bus.addOnNotFCBUS(fcMEM.getOut(0));
		

	}
	
	public static void ispisiSignale() {
		
		System.out.println("\n MemOper: rdMEM="+rdMEM.getOut(0).getBoolVal()+" wrMEM="+wrMEM.getOut(0).getBoolVal()+" DOUT="+RAM.getOut(0).getIntVal()
				+" MEMout="+MemUprav.MEMout.getOut(0).getBoolVal()+" fcMEM="+fcMEM.getOut(0).getBoolVal());
		
	/*	System.out.println("\n Sadrzaj RAM-a:");
		for ( int i=0 ; i<60 ; i++ ) { 
			if ( i%15==0 ) System.out.println();
			System.out.print("     ["+(i+256)+"]:"+RAM.read(i+256)); 
		}*/
		
	}

	public static MEM getMEM() {
		return RAM;
	}

}
